﻿using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace WPay.Infrastructure.Unity
{
    /// <summary>
    /// JSON序列化和反序列化
    /// </summary>
    public static class JSONSerializer
    {

        /// <summary>
        /// 将对象转换为JSON字符串
        /// </summary>
        /// <param name="obj">要序列化的对象</param>
        /// <returns></returns>
        public static string Serialize(object obj)
        {
            //设置日期格式化
            var iso = new IsoDateTimeConverter();
            iso.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            string str = JsonConvert.SerializeObject(obj, iso);



            //处理1970-01-01以后的日期字符串
            str = Regex.Replace(str, @"\\/Date\((-?\d+)\)\\/", match =>
            {
                DateTime dt = new DateTime(1970, 1, 1);
                dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));
                dt = dt.ToLocalTime();
                return dt.ToString("yyyy-MM-dd HH:mm:ss");
            });


            ////处理1970-01-01以后的日期字符串
            //str = Regex.Replace(str, @"\\/Date\((\d+)\)\\/", match =>
            //{
            //    DateTime dt = new DateTime(1970, 1, 1);
            //    dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));
            //    dt = dt.ToLocalTime();
            //    return dt.ToString("yyyy-MM-dd HH:mm:ss");
            //});
            ////str = str.Replace(@"\/Date(-62135596800000)\/", "");
            ////处理1970-01-01以前的日期字符串
            //str = Regex.Replace(str, @"\\/Date\((-\d+)\)\\/", match =>
            //{
            //    DateTime dt = new DateTime(1970, 1, 1);
            //    dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));
            //    dt = dt.ToLocalTime();
            //    return dt.ToString("yyyy-MM-dd HH:mm:ss");
            //});
            str = str.Replace(":null", ":\"\"");
            return str;
        }
        /// <summary>
        /// 将指定的 JSON 字符串转换为 T 类型的对象
        /// </summary>
        /// <typeparam name="T">所生成对象的类型</typeparam>
        /// <param name="input">要进行反序列化的JSON字符串</param>
        /// <returns></returns>
        public static T Deserialize<T>(string input)
        {
            try
            {
                return JsonConvert.DeserializeObject<T>(input);
                //return js.Deserialize<T>(input);
            }
            catch (Exception)
            {
                return default(T);
            }
        }
        /// <summary>
        /// 将指定的 T 类型的对象 转换为 Hashtable
        /// </summary>
        /// <typeparam name="T">所生成对象的类型</typeparam>
        /// <param name="input">要进行反序列化的JSON字符串</param>
        /// <returns></returns>
        public static Hashtable DeserializeToHashtable<T>(T t)
        {
            try
            {
                return JsonConvert.DeserializeObject<Hashtable>(Serialize(t));
            }
            catch (Exception)
            {
                return null;
            }
        }
        /// <summary>
        /// 将指定的 JSON 字符串转换为对象
        /// </summary>
        /// <param name="input">要进行反序列化的JSON字符串</param>
        /// <returns></returns>
        public static object DeserializeObject(string input)
        {
            try
            {
                return JsonConvert.DeserializeObject(input);
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 将对象转换为Json
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ObjToJson(object value)
        {
            try
            {
                var json = new Newtonsoft.Json.JsonSerializer
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace,
                    MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore,
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                };
                var sw = new System.IO.StringWriter();
                var writer = new JsonTextWriter(sw) { Formatting = Formatting.None, QuoteChar = '"' };
                json.Serialize(writer, value);
                var output = sw.ToString();
                writer.Close();
                sw.Close();
                return output;
            }
            catch (Exception)
            { return string.Empty; }
        }

        /// <summary>
        /// 将Json字符串转换为对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="jsonText"></param>
        /// <returns></returns>
        public static T JsonToObj<T>(string jsonText)
        {
            try
            {
                var json = new Newtonsoft.Json.JsonSerializer
                {
                    NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
                    ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace,
                    MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore,
                    ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
                };
                var sr = new System.IO.StringReader(jsonText);
                var reader = new JsonTextReader(sr);
                var result = (T)json.Deserialize(reader, typeof(T));
                reader.Close();
                return result;
            }
            catch (Exception)
            { return default(T); }
        }


        /// <summary>
        /// 反序列化JSON到给定的匿名对象.
        /// </summary>
        /// <typeparam name="T">匿名对象类型</typeparam>
        /// <param name="json">json字符串</param>
        /// <param name="anonymousTypeObject">匿名对象</param>
        /// <returns>匿名对象</returns>
        public static T DeserializeAnonymousType<T>(string json, T anonymousTypeObject)
        {
            T t = JsonConvert.DeserializeAnonymousType(json, anonymousTypeObject);
            return t;
        }
    }
}
